package chloroform.json.comp

import chloroform.json.{JsonBuilderFactory, CookiePropertyProcessingContext, GenericFactoryForElement}
import scaladuct.{Property, PropertyValue}
import java.util.Iterator
import scaladuct.l10n.PropertyValueMeta
import argo.jdom.JsonRootNode

/**
 * User: zslajchrt
 * Date: 16.5.11
 * Time: 19:43
 */
object Lists {
  def getConstructors =
    List(new CookieListItemsConstructor)
}

class ListItems extends JsonComposite {
  val data = array(array(string()))
  val editable = boolean()
  val multiChoice = boolean()
}

class ListItemsHolder extends JsonComposite {
  val ListItems = struct(new ListItems())
}

class CookieListItemsConstructor
  extends GenericFactoryForElement[PropertyValue[_], CookiePropertyProcessingContext, JsonBuilderFactory[JsonRootNode]] {

  def create(property: PropertyValue[_], ctx: CookiePropertyProcessingContext): Option[JsonBuilderFactory[JsonRootNode]] = {
    ctx.cookieGateway.pageExtension(classOf[scaladuct.lists.ListsManager]) match {
      case None => None
      case Some(listsManager) => {
        listsManager.listForProperty(property.asInstanceOf[Property[AnyRef]]) match {
          case None => None
          case Some(listForProperty) => {
            val listItemsHolder = new ListItemsHolder
            listItemsHolder.ListItems().editable <= listForProperty.editable
            listItemsHolder.ListItems().multiChoice <= listForProperty.multiChoice

            // localize the list of items
            var items: List[List[String]] = Nil
            val itemIter: Iterator[AnyRef] = listForProperty.content.iterator
            while (itemIter.hasNext) {
              val item = itemIter.next()
              val itemValue = "" + item

              ctx.cookieGateway.pageExtension(classOf[scaladuct.l10n.HasHintsMetaDataSource]) match {
                case None => {
                  items ::= List(itemValue, "", "")
                }
                case Some(mtdSource) => {
                  val mtdForValue = new PropertyValueMeta(mtdSource, ctx.locale,
                    listForProperty.property.asInstanceOf[PropertyValue[AnyRef]].update(item))
                  items ::= List(itemValue, mtdForValue.title(itemValue), mtdForValue.description(""))
                }
              }
            }

            listItemsHolder.ListItems().data <= items

            Some(listItemsHolder)
          }
        }
      }
    }
  }

}

